package com.hhkj.study.admin.user.service.extend.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hhkj.study.admin.resource.model.podo.ResourceCourseVideoPo;
import com.hhkj.study.admin.resource.service.extend.ResourceCourseVideoExtendService;
import com.hhkj.study.admin.user.entity.UserListen;
import com.hhkj.study.admin.user.model.podo.UserListenDo;
import com.hhkj.study.admin.user.model.podo.UserListenPo;
import com.hhkj.study.admin.user.service.base.UserListenService;
import com.hhkj.study.admin.user.service.extend.UserListenExtendService;
import com.ruoyi.common.base.biz.service.extend.BaseExtendServiceImpl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.cont.SysConst;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
*
* @author SERVER
* @since 2024-09-06
*/
@Service
public class UserListenExtendServiceImpl extends BaseExtendServiceImpl<UserListen, UserListenDo, UserListenPo, UserListenService> implements UserListenExtendService {

    @Resource
    private ResourceCourseVideoExtendService videoExtendService;

    @Override
    public boolean saveListenRecord(UserListenDo listenRecordDo) {
        List<UserListen> userListenList = listByUserCourseIdVideoId(listenRecordDo.getUserId(), listenRecordDo.getOrderItemId(), listenRecordDo.getCourseId(), listenRecordDo.getVideoId());
        boolean isUpdate = false;
        // 获取存在表中最长时长的听课记录
        UserListen existMaxDurationUserListen = null;
        Date recordStartTime = listenRecordDo.getStartStudyTime();
        if (CollectionUtil.isNotEmpty(userListenList)) {
            isUpdate = true;
            // 最新的听课记录 听课时长最长的
            Pair<UserListen, UserListen> userListenPair = userListenList.stream().collect(Collectors.collectingAndThen(
                    Collectors.toList(),
                    list -> {
                        UserListen userListenMaxTime = userListenList.stream()
                                .max(Comparator.comparing(UserListen::getEndStudyTime
                                        , Comparator.nullsLast(Comparator.naturalOrder()))).get();
                        UserListen userListenMaxDuration = userListenList.stream()
                                .max(Comparator.comparing(UserListen::getListenedDuration)).get();
                        return Pair.of(userListenMaxTime, userListenMaxDuration);
                    }));
            UserListen userListenMaxTime = userListenPair.getLeft();
            listenRecordDo.setId(userListenMaxTime.getId());
            if (ObjectUtil.isNotEmpty(userListenMaxTime.getStartStudyTime())) {
                listenRecordDo.setStartStudyTime(null);
            } else {
                listenRecordDo.setStartStudyTime(ObjectUtil.isEmpty(userListenMaxTime.getStartStudyTime())
                        ? recordStartTime : userListenMaxTime.getStartStudyTime());
            }
            existMaxDurationUserListen = userListenPair.getRight();
            if (ObjectUtil.isNotEmpty(existMaxDurationUserListen)) {
                listenRecordDo.setListeningStatus(existMaxDurationUserListen.getListeningStatus());
            }
        }
        return saveOrUpdateUserListen(existMaxDurationUserListen, listenRecordDo, isUpdate);
    }

    @Override
    public List<UserListen> listByUserCourseIdVideoId(Long userId, Long orderItemId, Long courseId, Long videoId) {
        LambdaQueryWrapper<UserListen> userListenQuery = new LambdaQueryWrapper<>();
        userListenQuery.eq(UserListen::getUserId, userId).eq(UserListen::getCourseId, courseId)
                .eq(UserListen::getOrderItemId, orderItemId).eq(UserListen::getVideoId, videoId);
        return this.getService().list(userListenQuery);
    }

    /**
     * 更新和保存用户听课记录
     * @param listenRecordDo
     * @param isUpdate
     */
    private boolean saveOrUpdateUserListen(UserListen userExistListen, UserListenDo listenRecordDo, boolean isUpdate) {
        ResourceCourseVideoPo resourceCourseVideo = videoExtendService.getPoByIdNotNull(listenRecordDo.getVideoId());
        // 有听课记录 听课时长>=视频总长度 表示完成
        if (ObjectUtil.isNotNull(resourceCourseVideo.getDuration())
                && listenRecordDo.getListenedDuration() >= resourceCourseVideo.getDuration()) {
            listenRecordDo.setListeningStatus(Constants.VIDEO_END_FLAG);
            listenRecordDo.setListenedDuration(resourceCourseVideo.getDuration());
        } else {
            if (listenRecordDo.getListenedDuration() > 0) {
                listenRecordDo.setListeningStatus(SysConst.Flag.IS.getFlag());
            } else {
                listenRecordDo.setListeningStatus(SysConst.Flag.NO.getFlag());
            }
        }
        if (isUpdate) {
            // 超过上一次观看时长就不更新,保存最后一次观看时长
            if (listenRecordDo.getListenedDuration() <= userExistListen.getListenedDuration()) {
                Long listenId = listenRecordDo.getId();
                UserListen lastListenRecord = new UserListen();
                lastListenRecord.setId(listenId);
                lastListenRecord.setLastListenedDuration(listenRecordDo.getListenedDuration());
                return this.getService().updateById(lastListenRecord);
            }
            if (ObjectUtil.isNotEmpty(userExistListen) && Constants.VIDEO_END_FLAG.equals(userExistListen.getListeningStatus())) {
                listenRecordDo.setListeningStatus(Constants.VIDEO_END_FLAG);
            }
            listenRecordDo.setLastListenedDuration(listenRecordDo.getListenedDuration());
            return this.getService().updateById(listenRecordDo);
        } else {
            listenRecordDo.setLastListenedDuration(listenRecordDo.getListenedDuration());
            listenRecordDo.setVideoDuration(resourceCourseVideo.getDuration());
            listenRecordDo.setVideoType(resourceCourseVideo.getType());
            return this.getService().save(listenRecordDo);
        }
    }
}
